package BuildTool;
use strict;
use Data::Dumper;
use Term::ReadKey;
use File::Find;
use Build;
use VCS;
use ITS;
use Cwd;

# Export the public subroutines to programs that use this module
BEGIN {
	require Exporter;
	our @ISA    = qw(Exporter);
	our @EXPORT = qw();

}

my $username = "";  #svn username
my %build_file_rev; #build_file_rev hash from the .txt file that will be updated
my %old_build_file_rev;        #original build_file_rev hash
my %build_file_rev_changes;    #file_rev_changes from polarion
my @params = ();               #params from buildParams.txt
my $type, my $prev_type, my $conf, my $number;    #build information
my $first_build = "false", my @files_fb;    #first build flag and files array
my $base_open_wi_allow;                     #flag related to the open work items
my $base_warn_suppress;    #flag related to the compiler and linker warnings
my $release_history;       #release history file
my $buildInfo;             #buildInfo file
my $buildParams;           #buildParams.txt
my $its_path, my $vcs_path, my $code_dir, my $rel_inc, my $project_name;
my $buildReport;

###############################################################################
# Function: getUsername
# This subroutine stores the username and allows backspace if the user makes a
# mistake.
#
# Inputs: String indicating the svn username.
# Returns: username
###############################################################################

sub getUsername {
	open(CMD,"whoami |");
	$username = <CMD>;
	chomp($username);
	return $username;
}

###############################################################################
# Function: readParams
# This subroutine reads the buildParams.txt and initializes the params array
# params[0] -> name, params[1] -> polarion_path, params[2] -> hex_name
# params[3] -> increment
#
# Inputs: buildParams name.
# Returns: Nothing.
###############################################################################

sub readParams {
	$buildParams = $_[1];
	my $line;
	my %conf_options;
	open( FILE, $buildParams ) or die "Couldn't find $buildParams";
	while ( $line = <FILE> ) {
		if ( $line =~ m/^#/ ) {

			#Do nothing, go to the next line
		}
		elsif ( $line =~ m/ = / ) {
			chomp $line;

			#Get the parameters after it matches the " = "
			push( @params, substr $line, "@+" );

		}
		elsif ($line =~ m/;/){
			my $config_number = substr $line, "@+";
			chomp($config_number);
			push @{$conf_options{substr $line, 0,"@-"}}, $config_number;
		}
	}
	if ( !( defined @params )) {
		die '$buildParams doesn\'t have enough parameters';
	}
	push (@params,\%conf_options);
	return \@params;
}

###############################################################################
# Function: defineBuildNumber
# This subroutine defines the build number, depending if it is the first build
# or not. If it is, the build number will be 1.1, otherwise the number will be
# the previous build number + 1.
#
# Inputs: First build flag, previous type and current type
# Returns: build number.
###############################################################################

sub defineBuildNumber {
	my $first_build = $_[1];
	my $prev_type   = $_[2];
	my $type        = $_[3];

	if ( $first_build eq "true" ) {
		return "1.1";
	}
	elsif ( $type eq "cron" ) {

		#Get only the digits in the string
		my @major_minor = $prev_type =~ /(\d+)/g;

		#If it's a cron the major number will be the index 0
		#The minor number will be the index 1 plus 1
		$major_minor[1] = $major_minor[1] + 1;
		return $major_minor[0] . "." . $major_minor[1];
	}
	else {

		#Get only the digits in the string
		my @major_minor = $prev_type =~ /(\d+)/g;

#If it's a baseline (and not the first) the major number will be in the index 0 plus 1
		$major_minor[0] = $major_minor[0] + 1;

		#The minor number will be 1
		$major_minor[1] = "1";
		return $major_minor[0] . "." . $major_minor[1];
	}
}

###############################################################################
# Function: checkIsFirstBuild
# This subroutine checks if it's the first build and enables or not the flag.
#
# Inputs: Release history location
# Returns: First build flag
###############################################################################

sub checkIsFirstBuild {

	#If the file release_history.txt exists, it is the first build
	my $file = $_[1];
	if ( -e $file ) {
		$first_build = "false";
	}
	else {
		$first_build = "true";
	}
	return $first_build;
}

###############################################################################
# Function: accessITS
# This function access the issue tracking system, to initialize the command
#line.
#
# Inputs: ITS path, project name, increment, type, base open work item allowed
#flag and buildReport file name.
# Returns: Nothing.
###############################################################################

sub accessITS {
	$its_path           = $_[1];
	$project_name       = $_[2];
	$rel_inc            = $_[3];
	$type               = $_[4];
	$base_open_wi_allow = $_[5];
	$buildReport        = $_[6];

	ITS->accessITS( $its_path, $project_name, $rel_inc, $type,
		$base_open_wi_allow, $buildReport );
}

###############################################################################
# Function: getPrevBuildName
# This subroutine reads the release history file and gets the previous build tag.
# If the build in progress is a baseline, it gets the previous baseline. If it's
# a cron, it gets the tag from the previous build.
#
# Inputs: Release history and build type
# Returns: Previous build tag
###############################################################################

sub getPrevBuildName {
	$prev_type = "";
	my $release_history_location = $_[1];
	$type = $_[2];

	#Read release history file
	open( READFILE, $release_history_location )
	  or die print "Couldn't open release history file.";
	my @line = <READFILE>;

	#If it's baseline, get from the previous baseline
	if ( $type eq "baseline" ) {
		my $i;
		for ( $i = 0 ; $i < scalar(@line) ; $i++ ) {
			if ( $line[$i] =~ m/base/ ) {
				$prev_type = $line[$i];
				chomp($prev_type);
				last;
			}
		}

	}
	elsif ( $type eq "cron" ) {

   #If it's a cron, get from the previous build (both cron or baseline are fine)
		$prev_type = $line[0];
		chomp($prev_type);
	}
	close(READFILE);
	print "\n\nPrevious Build: ", $prev_type, "\n\n";
	return $prev_type;
}

###############################################################################
# Function: getBuildInfo
# This subroutine gets the buildInfo.txt from the previous build/code/build in the
#repository.
#
# Inputs: Previous build type and buildInfo.txt
# Returns: Nothing
###############################################################################

sub getBuildInfo {
	$prev_type = $_[1];
	$buildInfo = $_[2];
	$vcs_path  = $_[3];

#Go to the build folder from the previous build, where the buildInfo.txt file is
	my $build_info_path =
	  $vcs_path . "/tags/" . $prev_type . "/code/build/" . $buildInfo;
	print
	  "\n-------------------------------------------------------------------\n";
	print
	  "                        GETTING BUILD INFO                           \n";
	print
	  "\n-------------------------------------------------------------------\n";

	#Export buildInfo.txt
	VCS->getBuildInfo($build_info_path);
}

###############################################################################
# Function: getRelHis
# This subroutine calls the VCS checkOutRelHis to checkout the rel_h.txt, passing
# the tags path.
#
# Inputs: Version control system path
# Returns: Nothing
###############################################################################

sub getRelHis {
	$vcs_path = $_[1];
	my $path = $vcs_path . "/tags";
	VCS->checkOutRelHis( $path, $username );
}

###############################################################################
# Function: getFileList
# This subroutine gets the revision and the vcs path to get the reference to
#the hash with the files and theirs revision and status (A - added, M- modified
# and D - deleted).
#
# Inputs: Revision and version control system path
# Returns: Reference to the hash Files->revision,status
###############################################################################

sub getFileList {
	my $revision = $_[1];
	my $vcs_path = $_[2];
	return VCS->getFileList( $revision, $vcs_path );
}

###############################################################################
# Function: getRevisions
# This subroutine calls the ITS->getRevisions()
#
# Inputs:Nothing.
# Returns:Reference to the revisions array.
###############################################################################

sub getRevisions {
	return ITS->getRevisions();
}

###############################################################################
# Function: readBuildInfoParams
# This subroutine converts the file (buildInfo)into a hash. The keys are the files,
# which are separated by space in the first line of .txt. Then, it gets the revisions
# in the second line of the file, that are also separated by space.
#
# Inputs: A file (buildInfo.txt).
# Returns: Reference to the build info hash.
###############################################################################

sub readBuildInfoParams {
	my $line;
	my %hash;
	my $buildInfo = $_[1];

	#Open buildInfo.txt file
	open( FILE, $buildInfo ) or die "couldn't open buildInfo file";
	$line = <FILE>;

	#Remove the new line character
	chomp $line;

	#Get the files in the first line, which are separated by space
	my @keys = split / /, $line;

	#Now get the revisions in the second line of the file.
	$line = <FILE>;

	#Remove \n character
	chomp $line;

	#The revisions are also separated by space and will be the values
	my @val = split / /, $line;

	#Insert the files and revision into the hash
	for ( my $i = 0 ; $i <= $#val ; $i++ ) {
		push @{ $hash{ $keys[$i] } }, $val[$i];
	}

	close(FILE);

	#Return the reference to the hash
	return \%hash;
}

###############################################################################
# Function: compRevLists
#
# This subroutine compares the build_file_rev (hash 1) and build_file_rev_changes
# (hash 2).If the hash 1 key exists in hash 2 and the value is equal, it remains in
# hash 1 and it will be deleted from hash 2. If the value is not equal, it adds the
# greater revision in hash 1 and deletes the smaller value from the proper hash.
# If the key doens't exist in hash 2, it remains in hash 1 (unchanged file).
# Then, if there's still keys and values in hash 2, it adds them into the hash 1
# if the status is not D.
#
# Example:
#
# -build_file_rev hash (hash 1):              -build_rev_changes (hash 2):
#
# file1.c -> 10                               file4.c -> [11,A]
# file1.h -> 10                               file1.c -> [15,M]
# file2.c -> 5                                file2.c -> [6,D]
# file3.c -> 8                                file5.c -> [13, M]
# file5.c -> 15
#
#
# -expected_final_hash (updated hash 1):
#
# file1.c -> 15
# file1.h -> 10
# file3.c -> 8
# file4.c -> 11
# file5.c -> 15
#
# Inputs: References to Hash 1 and hash 2.
# Returns: Final file/revision hash
###############################################################################

sub compRevLists {
	my $build_file_rev_ref         = $_[1];
	my $build_file_rev_changes_ref = $_[2];
	my $first_build = $_[3];
	my @added_files                = ();
	my @deleted_files              = ();
	my @modified_files             = ();
	my @unchanged_files            = ();
	%build_file_rev         = %$build_file_rev_ref;
	%build_file_rev_changes = %$build_file_rev_changes_ref;

	#Get a copy of the build_file_rev before comparison
	%old_build_file_rev = %build_file_rev;

	print "\n---------------------------------------------\n";
	print "\n Build info list and Polarion list comparison\n";
	print "\n---------------------------------------------\n";

	#Go to every hash 1 file
	foreach ( keys %build_file_rev ) {
		my $current_file = $_;

		#See if the file exists in hash 2
		if ( exists $build_file_rev_changes{$current_file} ) {

			#Get the revision array from hash 1
			my @r1 = @{ $build_file_rev{$current_file} };

			#Get the revision/status array from hash 2
			my @r2 = @{ $build_file_rev_changes{$current_file} };

			#r2[0] is the revision and r2[1] is the status
			#If the status is D, delete from both hash 1 and 2
			if ( $r2[1] eq "D" ) {
				push( @deleted_files, $current_file );
				print "the $current_file was DELETED \n";
				delete $build_file_rev{$current_file};
				delete $build_file_rev_changes{$current_file};
			}

			#The status is M
			else {

		#Case when the revision from hash 1 is equal to the revision from hash 2
				if ( $r1[0] == $r2[0] ) {
					print "the revision $r1[0] of $current_file is EQUAL \n";

					#Remain in hash 1 and it is deleted from hash 2
					delete $build_file_rev_changes{$current_file};
				}


				#Case when the revision from hash 1 is smaller than the hash 2
				elsif ( $r1[0] < $r2[0] ) {
					#Delete from hash 1
					delete $build_file_rev{$current_file};
					print
"the revision $r1[0] of $current_file from hash 1 is SMALLER \n";
				}

				#Case when the revision from hash 1 is greater than the hash 2
				else {

					#Delete the from hash 2
					delete $build_file_rev_changes{$current_file};
					print
"the revision $ r1[0] of $_ from hash 1 is GREATER - This should not happen\n";
				}
			}
		}
		else {

#If the file doesn't exist in hash 2, it is an unchanged file and needs to be in the
#final hash 1
			print "the revision of $current_file from hash 1 is UNCHANGED \n";
			my @r1 = @{ $build_file_rev{$current_file} };
			push( @unchanged_files, $current_file . " " . $r1[0] );
		}
	}

	#The files that remained in hash 2 will be added in hash 1 because they are
	# added or modified files
	if ( keys %build_file_rev_changes ) {
		foreach ( keys %build_file_rev_changes ) {
			if((($_ =~ /trunk\/code\//) || ($_ =~ /trunk\/tools\//)))
			{
				my @r = @{ $build_file_rev_changes{$_} };
	
				#Case when the file exists in hash 2 with D status and not in hash 1
				if ( $r[1] eq "D" ) {
					push( @deleted_files, $_ . " " . $r[0] );
					print "the $_ was DELETED \n";
					delete $build_file_rev_changes{$_};
				}
				else {
					if ($r[1] eq "A") {
						push( @added_files, $_ . " " . $r[0]);
					}
					elsif ($r[1] eq "M") {
						push( @modified_files, $_ . " " . $r[0]);
					}
					#Adding the A and M files.
					print "the $_ revision - $r[0] was ADDED \n";
					push @{ $build_file_rev{$_} }, $r[0];
					delete $build_file_rev_changes{$_};
				}
			}
		}
	}
	print "\n---------------------------------------\n";
	print "                  FINAL HASH              ";
	print "\n---------------------------------------\n";
	print Dumper( \%build_file_rev );
	#If it's the first build, all the files were added.
	if ($first_build eq "true") {
		foreach my $key (keys %build_file_rev){
			my @r = @{ $build_file_rev{$key} };
			push( @added_files, $key . " " . $r[0]);
		}
		
	}
	updateBuildReportADMFiles( \@deleted_files, \@added_files, \@modified_files,
		\@unchanged_files );
	return \%build_file_rev;
}

###############################################################################
# Function: checkChangesCrons
# This subroutine checks if there are changes between the old_build_file_rev
# and the build_file_rev. If there're no changes it fails. This subroutine will
# be used to not let the person have 2 consecutive crons that are equal.
#
# Inputs: References to the build_file_rev and the old_build_file_rev
# Returns: Nothing
###############################################################################

sub checkChangesCrons {
	my $n_changes              = 0;
	my $build_file_rev_ref     = $_[1];
	my $old_build_file_rev_ref = $_[2];
	%build_file_rev     = %$build_file_rev_ref;
	%old_build_file_rev = %$old_build_file_rev_ref;

	#Go to each key in the build_file_rev and see if the file
	#exists in the old_build_rev
	foreach ( keys %build_file_rev ) {
		if ( exists $old_build_file_rev{$_} ) {

			#Get the revisions arrays
			my @old_build_file_rev_array = @{ $old_build_file_rev{$_} };
			my @build_file_rev_array     = @{ $build_file_rev{$_} };

			#If the file exists, see if the revision is the same
			if ( $build_file_rev_array[0] eq $old_build_file_rev_array[0] ) {

				#Do nothing, because they are equal
			}
			else {

				#If the revisions are not equal, increment the number of changes
				$n_changes++;
			}
		}
		else {

			#If the files are not equal, increment the number of changes
			$n_changes++;
		}
	}

#If there are no changes the tool will fail, because you can't make two consecutive equal crons
	if ( $n_changes == 0 ) {
		die "There are no changes since the last cron";
	}
}

###############################################################################
# Function: checkOut
# This subroutine calls the VCS->createWorkCopy() to create a working copy and
# VCS->exportFiles() to export the specified files from the build_file_rev.
# If it's the first build, will checkout from the trunk.
#
# Inputs: Reference to the file/revisions hash and repository path
# flag.
# Returns: Nothing.
###############################################################################

sub checkOut {
	print "\n--------------------------------------------------------------\n";
	print "\n             CREATING REPOSITORY WORKING COPY                 \n";
	print "\n--------------------------------------------------------------\n";

	my $file;
	my $rev;
	my $past_path;
	my $build_file_rev_ref = $_[1];
	%build_file_rev = %$build_file_rev_ref;
	my $vcs_path = $_[2];

	VCS->createWorkCopy( $vcs_path . "/trunk" );
	print "\n--------------------------------------------------------------\n";
	print "\n                       EXPORTING FILES                        \n";
	print "\n--------------------------------------------------------------\n";
	foreach my $file ( sort keys %build_file_rev ) {

		#Get the revision/status array
		my @rv_st = @{ $build_file_rev{$file} };

		#Get just the revision
		$rev = $rv_st[0];
		print "REV ", $rev, " file ", $file, "\n";

		#Export the specified file/revision from build_file_rev
		$past_path = VCS->exportFiles( $rev, $file );
	}

	#Go to the build tool directory
	chdir($past_path);

}

###############################################################################
# Function: buildCode
# This subroutine calls the Build->buildCode to build the code depending on
# its configuration (Debug, Release, ReleaseRTLx).
#
# Inputs: Code directory
# Returns: Nothing.
###############################################################################

sub buildCode {
	my $code_dir = $_[1];
	my $type = $_[2];
	my $number = $_[3];
	my $conf_number = $_[4];
	my $conf = $_[5];
	#Change the fillcode.c file with the build tag, conf and timestamp
    changeBuildRevInfo($code_dir,$type,$number,$conf_number,$conf);
	Build->buildCode($code_dir,$conf);

}

###############################################################################
# Function: analyzeCompLinkEW
# This subroutine calls the Build->analyzeCompLinkEW() to see if there are
# compiler/linker errors or warnings. If the build is successful, the tool will
# update the build report with the successful status.
#
# Inputs: Base warning surpress flag, build report path
# Returns: Nothing.
###############################################################################

sub analyzeCompLinkEW() {
	my $base_warn_suppress = $_[1];
	my $build_report_path  = $_[2];
	my $conf = $_[3];
	my $pathToSourceCode = $_[4]; 
	my $successStatus = Build->analyzeCompLinkEW( $base_warn_suppress, $conf,$pathToSourceCode );
	if($successStatus == 1)
	{
		Build->updateBuildReportStatus( $build_report_path, $buildReport, $pathToSourceCode,
			"Successful" );
	}
	else
	{
		# failed build
		Build->updateBuildReportStatus( $build_report_path, $buildReport, $pathToSourceCode,
			"FAILED" );
		die "Build failed - see build report for more information.\n";
	}
}

###############################################################################
# Function: genBuildInfo
# This subroutine creates the builInfo.txt based on the build_file_rev. The first
# line is just the files (separated by space) and the second line is just the
# revisions (also separated by space).
#
# Inputs: Code directory, trunk folder name, first build and cron flag,
# buildInfo file and repository path
# Returns: Nothing.
###############################################################################

sub genBuildInfo {
	$code_dir = $_[1];
	my $trunk = $_[2];
	$buildInfo = $_[3];
	$vcs_path  = $_[4];

	#Get current path
	my $build_tool_dir = getcwd();

	#Update the file based on the file->revision hash.
	my $file;
	my @files = ();
	my $rev;
	my @revs = ();

	#Go to each file in the build_file_rev array
	foreach my $file ( sort keys %build_file_rev ) {

		#Get the revision/status array
		my @rv_st = @{ $build_file_rev{$file} };

		#Get the revision
		$rev = $rv_st[0];

		#Add the file to all files hash
		push @files, $file;

		#Add the revision to all revisions hash
		push @revs, $rev;
	}

	#Enter the build folder because the buildInfo.txt will be generated there
	chdir( $code_dir . "/code/build" );

	#Create buildInfo.txt
	open( FILE, '>' . $buildInfo )
	  or die print "Can't create buildInfo.txt";

	#Insert files in the first line, separated by space
	for ( my $i = 0 ; $i < scalar(@files) ; $i++ ) {
		print FILE $files[$i] . " ";
	}

	#Jump line
	print FILE "\n";

	#Insert revisions in the second line, separated by space
	for ( my $i = 0 ; $i < scalar(@revs) ; $i++ ) {
		print FILE $revs[$i] . " ";
	}
	close(FILE);

	#Go back to the previous path
	chdir($build_tool_dir);
	print "\n buildInfo created\n";

	#Remove old buildInfo.txt in the build tool path
	system( "rm -rf " . $buildInfo );
}

###############################################################################
# Function: tagBuild
# This subroutine calls the VCS->tagBuild to add and tag the files.
#
# Inputs: Build number.
# Returns: Nothing.
###############################################################################

sub tagBuild {
	$number = $_[1];
	VCS->tagBuild( $vcs_path, $type, $number, $code_dir );
}

###############################################################################
# Function: updateRelHist
# This subroutine calls Build->updateRelHist to update the release history
# file with the new tag and then commit the file to the tags folder
#
# Inputs:Release history path, first base flag, build type and number
# Returns:Nothing.
###############################################################################

sub updateRelHist {
	my $release_history_location = $_[1];
	my $type                     = $_[2];
	my $number                   = $_[3];
	Build->updateRelHist( $first_build, $release_history_location, $type,
		$number );
	
#Commit the updated file
system("svn commit -m \"$release_history_location updated\" $release_history_location");
}

###############################################################################
# Function: createBuildReport
# This subroutine creates the buildReport with the date/time, arm linker and
# compiler, svn and build tool versions. It also calls the updateBuildReportADMFiles
# subroutine to write the added, deleteded, modified and unchanged files. 
#
# Inputs: Build report name
# Returns: Nothing.
###############################################################################

sub createBuildReport {
	$buildReport = $_[1];
	

	#Create new buildReport File
	open( FILE, ">$buildReport" );
	print FILE "BUILD TOOL REPORT \n\n";
	print FILE "SUMMARY: \n\n";

	#Get date and time and then print
	my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
	  localtime(time);
	my $month = (
		"January",   "February", "March",    "April",
		"May",       "June",     "July",     "August",
		"September", "October",  "November", "December"
	)[$mon];
	my $timestamp = sprintf "$month %02d, %04d  %02d:%02d", $mday, $year + 1900,
	  $hour, $min;
	print FILE "RUN TIME: $timestamp\n";

	#Print the username
	print FILE "USER: $username\n\n";

	#Get arm compiler version and then print
	open( ARMC, "armcc --version_number|" );
	my $version_number = <ARMC>;
	print FILE "TOOLS USED: \n\n";
	print FILE "ARM COMPILER VERSION: $version_number";
	close ARMC;

	#Get arm linker version and then print
	open( ARML, "armlink --version_number|" );
	$version_number = <ARML>;
	print FILE "ARM LINKER VERSION: $version_number";
	close ARML;

	#Get svn version and then print
	open( SVN, "svn --version|" );
	$version_number = <SVN>;

	if ( $version_number =~ /version / ) {
		$version_number = substr( $version_number, "@+" );
	}
	print FILE "SVN VERSION: $version_number";
	close SVN;

	#Get buildtool version and then print
	open( BUILDTOOL, "svnversion|" );
	$version_number = <BUILDTOOL>;

	#The svnversion output is the range of revisions in this
	# format: NN:NN status (e.g. M for modified or S for switched).
	#The tool only needs the number after the ":"
	if ( $version_number =~ /:/ ) {

		#Remove the number before ":"
		$version_number = substr( $version_number, "@+" );
	}
	if ( $version_number =~ /[A-Z]/ ) {

		#Remove the status after the number
		$version_number = substr( $version_number, 0, "@-" );
	}
	print FILE "BUILD TOOL VERSION: $version_number\n\n";

	close BUILDTOOL;
	close FILE;
}

###############################################################################
# Function: updateBuildReportITS
# This subroutine calls the updateBuildReport in ITS module
#
# Inputs: Nothing.
# Returns: Nothing.
###############################################################################

sub updateBuildReportITS {
	ITS->updateBuildReport;
}

###############################################################################
# Function: updateBuildReportADMFiles
# This subroutine updates the buildReport.txt with the added, deleted, modified
# and unchanged files.
#
# Inputs: Deleted files reference, added files reference, modified files reference
# and unchanged files reference.
# Returns: Nothing.
###############################################################################

sub updateBuildReportADMFiles {
	my $del_ref = $_[0];
	my $add_ref = $_[1];
	my $mod_ref = $_[2];
	my $unc_ref = $_[3];
	my @add     = @$add_ref;
	my @del     = @$del_ref;
	my @mod     = @$mod_ref;
	my @unc     = @$unc_ref;
	open( FILE, ">>$buildReport" );
	print FILE "\n\nADDED Files\n\n";

	foreach my $add_file (@add) {
		print FILE $add_file, "\n";
	}
	print FILE "\n\nDELETED Files\n\n";
	foreach my $del_file (@del) {
		print FILE $del_file, "\n";
	}
	print FILE "\n\nMODIFIED Files\n\n";
	foreach my $mod_file (@mod) {
		print FILE $mod_file, "\n";
	}
	print FILE "\n\nUNCHANGED Files\n\n";
	foreach my $unc_file (@unc) {
		print FILE $unc_file, "\n";
	}
	close FILE;
}

###############################################################################
# Function: changeFillCode
# This subroutine reads and modifies fillcode.c file in orde to write the 
# build major, minor and configuration
#
# Inputs: Code directory, build type, number and configuration.
# Returns: Nothing.
###############################################################################

sub changeBuildRevInfo {

my $code_dir = $_[0];
my $type = $_[1];
my $number = $_[2];
my $conf_number = $_[3];
my $file = $code_dir . "/code/shared_app/fillcode.c";
my @major_minor = split(/\./,$number);
my $build_conf_number;



#Get date and time and then print them
my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime(time);
my $month = ("Jan","Feb","Mar","Apr", "May", "June","July", "Aug","Sept", "Oct",  "Nov", "Dec")[$mon];
my $week_day = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")[$wday];
my $date_time_stamp = sprintf("%3s %3s %2d %02d:%02d:%02d UTC %4d", $week_day, $month, $mday, $hour,$min,$sec, $year + 1900 );

#Read fillcode.c
open(FILE,"<$file");
my $line;
my @new_lines = ();
while ($line = <FILE>){
	#Wrtie date_time_stamp
	if($line =~ /		"Sun Jan  1 00:00:00 UTC 1900 ",/){
		$line = "\t\t\"$date_time_stamp\",\n";
	}
	
	push(@new_lines,$line);
}
close FILE;
system("rm -rf $file");

open(FILE,">$file");
print FILE @new_lines;
close FILE;

$file = $code_dir . "/code/shared_app/build_rev_info.h";

open(FILE,"<$file");
@new_lines = ();
while ($line = <FILE>){
	#Write baseline major
	if(($line =~ /BASE_MAJOR_REV/) && ($type eq "baseline"))  {
		my $hex = sprintf("0x%x",$major_minor[0]);
		$line = "#define BASE_MAJOR_REV $hex\n";
	}
	#Write baseline minor
	if(($line =~ /BASE_MINOR_REV/) && ($type eq "baseline")) {
		my $hex = sprintf("0x%x",$major_minor[1]);
		$line = "#define BASE_MINOR_REV $hex\n";
	}
	#Write cron major
	if(($line =~ /CRON_MAJOR_REV/) && ($type eq "cron")) {
		my $hex = sprintf("0x%x",$major_minor[0]);
		$line = "#define CRON_MAJOR_REV $hex\n";
	}
	#Write cron minor
	if(($line =~ /CRON_MINOR_REV/) && ($type eq "cron")) {
		my $hex = sprintf("0x%x",$major_minor[1]);
		$line = "#define CRON_MINOR_REV $hex\n";
	}
	#Write build configuration
	if($line =~ /BUILD_TYPE/) {
		my $hex = sprintf("0x%x",$conf_number);
		$line = "#define BUILD_TYPE $hex\n";
	}
	push(@new_lines,$line);
}
close FILE;
system("rm -rf $file");

open(FILE,">$file");
print FILE @new_lines;
close FILE;

}

1;

